package com.zxy.service.impl;



import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxy.common.annotation.AutoFill;
import com.zxy.common.enumeration.OperationType;
import com.zxy.common.result.PageResult;
import com.zxy.common.result.Result;
import com.zxy.mapper.*;
import com.zxy.pojo.dto.ClueFalseDto;
import com.zxy.pojo.dto.CluePageQueryDto;
import com.zxy.pojo.entity.*;
import com.zxy.service.ClueService;
import com.zxy.service.OpportunityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class ClueServiceImpl extends ServiceImpl<ClueMapper,Clue> implements ClueService {

    @Autowired
    private ClueMapper clueMapper;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private ClueAssignRecordMapper assignRecordMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private OpportunityService opportunityService;

    @Autowired
    private ClueTrackRecordMapper clueTrackRecordMapper;


    /**
     * 分页查询线索列表
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult selectCluelist(CluePageQueryDto dto) {
        log.info("开始查询线索列表，参数: {}", dto);

        // 计算偏移量
        int offset = (dto.getPageNum() - 1) * dto.getPageSize();
        dto.setPageNum(offset);

        List<Clue> list = clueMapper.selectCluelist(dto);
        Long total = clueMapper.countCluelist(dto);

        log.info("线索列表查询完成，总记录数: {}，当前页记录数: {}", total, list.size());
        return new PageResult(total, list);
    }

    /**
     * 新增线索
     *
     * @param clue
     * @return
     */
    @Override
    public Result add(Clue clue) {
        log.info("添加线索，参数: {}", clue);
        clue.setCreateTime(new Date());
        clue.setUpdateTime(new Date());
        clueMapper.insertClue(clue);
        ClueAssignRecord assignRecord = new ClueAssignRecord();
        assignRecord.setAssignId(clue.getId());
        assignRecord.setUserId(clue.getUserId());
        assignRecord.setUserName(clue.getCreateBy());
        assignRecord.setCreateBy(clue.getCreateBy());
        assignRecord.setCreateTime(new Date());
        assignRecordMapper.insertAssignRecord(assignRecord);
        return Result.success();
    }

    /**
     * 查询线索详细信息
     *
     * @param id
     * @return
     */
    @Override
    public Clue selectClueById(Long id) {
        Clue clue = clueMapper.selectClueById(id);
        if (clue != null && clue.getActivityId() != null) {
            Activity activity = activityMapper.selectActivityById(clue.getActivityId());
            if (activity != null) {
                clue.setActivityInfo(activity.getCode() + ":" + activity.getName() + ":" + activity.getInfo());
            }
        }
        return clue;
    }

    /**
     * 线索池分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult cluePoolPageQuery(CluePageQueryDto dto) {
        log.info("开始查询线索列表，参数: {}", dto);

        // 计算偏移量
        int offset = (dto.getPageNum() - 1) * dto.getPageSize();
        dto.setPageNum(offset);

        List<Clue> list = clueMapper.cluePoolPageQuery(dto);
        Long total = clueMapper.countCluePoollist(dto);

        log.info("线索列表查询完成，总记录数: {}，当前页记录数: {}", total, list.size());
        return new PageResult(total, list);
    }

    /**
     * 分配线索
     *
     * @param clueIds
     * @param userId
     * @return
     */
    @Override
    public String assignment(Long[] clueIds, Long userId) {

        log.info("开始分配线索，线索ID列表: {}，用户ID: {}", clueIds, userId);

        // 查询当前用户已分配的线索数
        int count = assignRecordMapper.countAssignClueByUser(userId);
        log.info("用户 {} 当前已分配线索数: {}", userId, count);

        if (count >= 3) {
            log.warn("用户 {} 已分配线索数达到上限3个", userId);
            return "当前用户已分配线索数达到上限";
        }

        // 查询分配的用户信息
        SysUser assignUser = userMapper.selectUserById(userId);
        if (assignUser == null) {
            log.error("用户ID {} 不存在", userId);
            return "分配用户不存在";
        }

        // 计算还能分配多少个线索
        int remainingSlots = 3 - count;
        log.info("用户 {} 还能分配 {} 个线索", userId, remainingSlots);

        // 遍历线索ID进行分配
        int assignedCount = 0;
        for (Long clueId : clueIds) {
            // 如果已达到分配上限，则停止分配
            if (assignedCount >= remainingSlots) {
                log.info("用户 {} 已达到分配上限 不可分配", userId);
                break;
            }

            // 查询线索信息
            Clue clue = clueMapper.selectClueById(clueId);
            if (clue == null) {
                log.warn("线索ID {} 不存在", clueId);
                continue;
            }

            clue.setUserId(userId);
            clue.setUpdateTime(new Date());
            clue.setOwner(assignUser.getUserName());
            clueMapper.updateClue(clue);

            // 添加分配记录
            ClueAssignRecord assignRecord = new ClueAssignRecord();
            assignRecord.setAssignId(clueId);
            assignRecord.setUserId(userId);
            assignRecord.setUserName(assignUser.getUserName());
            assignRecord.setCreateBy(clue.getCreateBy());
            assignRecord.setCreateTime(new Date());
            assignRecord.setLatest("1");
            assignRecord.setType("0");
            assignRecordMapper.insertAssignRecord(assignRecord);
            assignedCount++;
        }

        return "成功分配 " + assignedCount + " 个线索";
    }

    /**
     * 捞取线索
     * @param clueId
     * @return
     */
    @Override
    public Result gainClue(Long clueId) {
        log.info("开始捞取线索,线索id = {}", clueId);
        
        try {
            // 查询线索是否存在
            Clue clue = this.getById(clueId);
            if (clue == null) {
                return Result.error("线索不存在,id = {} " + clueId);
            }

            // 验证线索是否在线索池中
            if (!"4".equals(clue.getStatus())) {
                return Result.error("该线索不在线索池中,无法捞取");
            }

            clue.setStatus("1");
            clue.setUpdateTime(new Date());
            
            // 更新线索
            boolean updateResult = this.updateById(clue);
            
            if (updateResult) {
                log.info("成功捞取线索,id = {}", clueId);
                return Result.success("捞取成功");
            } else {
                log.error("捞取线索失败,id = {}", clueId);
                return Result.error("捞取失败");
            }
        } catch (Exception e) {
            log.error("捞取线索时发生错误", e);
            return Result.error("捞取失败: " + e.getMessage());
        }
    }

    /**
     * 伪线索
     * @param dto
     * @param clueId
     * @return
     */
    @Override
    public Result markAsFalseClue(ClueFalseDto dto, Long clueId) {
        Long id = clueId != null ? clueId : dto.getClueId();
        log.info("标记为伪线索, clueId = {}, dto = {}", id, dto);
        if (id == null) {
            return Result.error("线索ID不能为空");
        }
        
        try {
            // 验证是否存在
            Clue existingClue = this.getById(id);
            if (existingClue == null) {
                return Result.error("线索不存在,id = {} " + id);
            }

            //记录原因
            if (dto != null && dto.getReason() != null) {
                log.info("伪线索原因: {}", dto.getReason());
            }
            //更新状态
            existingClue.setStatus("4");
            existingClue.setUpdateTime(new Date());
            boolean updateResult = this.updateById(existingClue);

            if (updateResult) {
                log.info("标记为伪线索,Id = {} ", id);
                return Result.success();
            } else {
                log.error("标记为伪线索失败,Id = {}", id);
                return Result.error("标记失败");
            }
        } catch (Exception e) {
            log.error("标记为伪线索时发生错误,线索id = {}", id, e);
            return Result.error("标记失败: " + e.getMessage());
        }
    }

    /**
     * 线索转商机
     * @param id
     * @return
     */
    @Override
    public Result changeBusiness(Long id) {
        log.info("开始线索转商机, 线索id = {}", id);

        // 线索是否存在
        Clue clue = this.getById(id);
        if (clue == null) {
            return Result.error("线索不存在, id = " + id);
        }

        // 验证线索状态
        if (!"2".equals(clue.getStatus())) {
            return Result.error("当前线索不能转为商机, 当前状态: " + clue.getStatus());
        }

        try {

            CustomerClue customerClue = new CustomerClue();
            // 复制基本属性
            customerClue.setName(clue.getName());
            customerClue.setPhone(clue.getPhone());
            customerClue.setChannel(clue.getChannel());
            customerClue.setActivityId(clue.getActivityId() != null ? clue.getActivityId().intValue() : null);
            customerClue.setActivityName(clue.getActivityName());
            customerClue.setActivityInfo(clue.getActivityInfo());
            customerClue.setSex(clue.getSex());
            customerClue.setAge(clue.getAge());
            customerClue.setWeixin(clue.getWeixin());
            customerClue.setQq(clue.getQq());
            customerClue.setLevel(clue.getLevel());
            customerClue.setStatus("1");
            customerClue.setOwner(clue.getOwner());
            customerClue.setNextTime(clue.getNextTime() != null ?
                    clue.getNextTime().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime() : null);
            customerClue.setUserId(clue.getUserId());
            customerClue.setTransfer(clue.getTransfer());
            customerClue.setCreateBy(clue.getCreateBy());
            customerClue.setCreateTime(clue.getCreateTime() != null ?
                    clue.getCreateTime().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime() : null);
            customerClue.setClueId(clue.getId());

            // 保存到商机表
            boolean saveResult = opportunityService.saves(customerClue);
            if (!saveResult) {
                log.error("保存商机失败, 线索id = {}", id);
                return Result.error("转商机失败");
            }


            // 删除线索跟进记录
            clueTrackRecordMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ClueTrackRecord>()
                    .eq(ClueTrackRecord::getClueId, id));

            // 删除线索
            boolean removeResult = this.removeById(id);
            if (!removeResult) {
                log.error("删除线索失败, 线索id = {}", id);
                throw new RuntimeException("删除线索失败");
            }

            log.info("线索转商机成功, 线索id = {}, 商机id = {}", id, customerClue.getId());
            return Result.success("线索转商机成功");

        } catch (Exception e) {
            log.error("线索转商机时发生错误, 线索id = {}", id, e);
            throw new RuntimeException("线索转商机失败: " + e.getMessage());
        }
    }
}
